# -*- coding: utf-8 -*-
# @Time    : 2019/10/27 12:10
# @Author  : LiHaowen
# @Email   : lihaowen2017@163.com
# @File    : progress_queue.py
import time
from multiprocessing import Process, Queue, Pool, Manager, Pipe
# Manager 用于进程间通讯
# from queue import Queue  多进程中不能使用普通的Queue
# queue = Queue(10)
#
#
# def producer(queue):
#     queue.put("a")
#     time.sleep(2)
#
#
# def consumer(queue):
#     time.sleep(2)
#     data = queue.get()
#     print(data)
#
#
# if __name__ == '__main__':
#     queue = Queue(10)
#     my_producer = Process(target=producer, args=(queue, ))
#     my_consumer = Process(target=consumer, args=(queue, ))
#     my_producer.start()
#     my_consumer.start()
#     my_producer.join()
#     my_consumer.join()


# 共享全局变量通信
# 共享全局变量不能适用于多进程编程，可以适用于多线程
# 多进程中数据完全隔离，当fork后，进程将数据完全复制一份到子进程中，两边数据做修改的时候不会影响

# def producer(a):
#     a += 1
#     time.sleep(2)
#
#
# def consumer(a):
#     time.sleep(2)
#     print(a)
#
#
# if __name__ == '__main__':
#     a = 1
#     my_producer = Process(target=producer, args=(a, ))
#     my_consumer = Process(target=consumer, args=(a, ))
#     my_producer.start()
#     my_consumer.start()
#     my_producer.join()
#     my_consumer.join()
#
# multiprocessing中的queue不能用于pool进程池间通讯
# pool中的进程间通讯需要使用manager中的queue
# python 中的三个Queue
from queue import Queue
from multiprocessing import Queue
from multiprocessing import Manager, Pipe

#
# def producer(queue):
#     queue.put("a")
#     time.sleep(2)
#
#
# def consumer(queue):
#     time.sleep(2)
#     data = queue.get()
#     print(data)
#
#
# if __name__ == '__main__':
#     queue = Manager().Queue(10)  # 必须要实例化manager
#     pool = Pool(2)
#
#     pool.apply_async(producer, args=(queue,))
#     pool.apply_async(consumer, args=(queue,))
#
#     pool.close()
#     pool.join()


# 通过pipe实现进程间通讯

# def producer(pipe):
#     pipe.send("a")
#     time.sleep(2)
#
#
# def consumer(pipe):
#     time.sleep(2)
#     data = pipe.recv()
#     print(data)
#
#
# if __name__ == '__main__':
#     reversed_pipe, send_pipe = Pipe()
#     # pipe 只能适用于两个指定的进程！！！
#     # pipe 性能高于queue
#     my_producer = Process(target=producer, args=(send_pipe,))
#     my_consumer = Process(target=consumer, args=(reversed_pipe,))
#
#     my_producer.start()
#     my_producer.join()
#     my_consumer.start()
#     my_consumer.join()


# 进程间通讯的其它方式
# 进程间共享内存操作
# Manager 中有常见的数据类型
# 使用时注意数据同步，Manager中LockRLock的使用

def add_data(p_dict, k, v):
    p_dict[k] = v


if __name__ == '__main__':
    progress_dict = Manager().dict()
    first_progress = Process(target=add_data, args=(progress_dict, "b1", 23))
    second_progress = Process(target=add_data, args=(progress_dict, "b2", 24))
    first_progress.start()
    second_progress.start()
    first_progress.join()
    second_progress.join()
    print(progress_dict)